<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>Decorator Basics - Zend Framework Manual</title>

    <link href="../css/shCore.css" rel="stylesheet" type="text/css" />
    <link href="../css/shThemeDefault.css" rel="stylesheet" type="text/css" />
    <link href="../css/styles.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Zend Framework</h1>
<h2>Programmer's Reference Guide</h2>
<ul>
    <li><a href="../en/learning.form.decorators.simplest.html">Inglês (English)</a></li>
    <li><a href="../pt-br/learning.form.decorators.simplest.html">Português Brasileiro (Brazilian Portuguese)</a></li>
</ul>
<table width="100%">
    <tr valign="top">
        <td width="85%">
            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="learning.form.decorators.intro.html">Introduction</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="learning.form.decorators.html">Understanding and Using Zend Form Decorators</a></span><br />
                        <span class="home"><a href="manual.html">Programmer's Reference Guide</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="learning.form.decorators.layering.html">Layering Decorators</a></div>
                    </td>
                </tr>
            </table>
<hr />
<div id="learning.form.decorators.simplest" class="section"><div class="info"><h1 class="title">Decorator Basics</h1></div>
    

    <div class="section" id="learning.form.decorators.simplest.decorator-overview"><div class="info"><h1 class="title">Overview of the Decorator Pattern</h1></div>
        

        <p class="para">
            To begin, we&#039;ll cover some background on the <a href="http://en.wikipedia.org/wiki/Decorator_pattern" class="link external">&raquo; Decorator design
                pattern</a>. One common technique is to define a common interface that both
            your originating object and decorator will implement; your decorator than accepts the
            originating object as a dependency, and will either proxy to it or override its methods.
            Let&#039;s put that into code to make it more easily understood:
        </p>

        <pre class="programlisting brush: php">
interface Window
{
    public function isOpen();
    public function open();
    public function close();
}

class StandardWindow implements Window
{
    protected $_open = false;

    public function isOpen()
    {
        return $this-&gt;_open;
    }

    public function open()
    {
        if (!$this-&gt;_open) {
            $this-&gt;_open = true;
        }
    }

    public function close()
    {
        if ($this-&gt;_open) {
            $this-&gt;_open = false;
        }
    }
}

class LockedWindow implements Window
{
    protected $_window;

    public function __construct(Window $window)
    {
        $this-&gt;_window = $window;
        $this-&gt;_window-&gt;close();
    }

    public function isOpen()
    {
        return false;
    }

    public function open()
    {
        throw new Exception(&#039;Cannot open locked windows&#039;);
    }

    public function close()
    {
        $this-&gt;_window-&gt;close();
    }
}
</pre>


        <p class="para">
            You then create an object of type <span class="classname">StandardWindow</span>, pass it to the
            constructor of <span class="classname">LockedWindow</span>, and your window instance now has
            different behavior. The beauty is that you don&#039;t have to implement any sort of &quot;locking&quot;
            functionality on your standard window class -- the decorator takes care of that for you.
            In the meantime, you can pass your locked window around as if it were just another
            window.
        </p>

        <p class="para">
            One particular place where the decorator pattern is useful is for creating textual
            representations of objects. As an example, you might have a &quot;Person&quot; object that, by
            itself, has no textual representation. By using the Decorator pattern, you can create an
            object that will act as if it were a Person, but also provide the ability to render that
            Person textually.
        </p>

        <p class="para">
            In this particular example, we&#039;re going to use <a href="http://en.wikipedia.org/wiki/Duck_typing" class="link external">&raquo; duck typing</a> instead of an
            explicit interface. This allows our implementation to be a bit more flexible, while
            still allowing the decorator object to act exactly as if it were a Person object.
        </p>

        <pre class="programlisting brush: php">
class Person
{
    public function setFirstName($name) {}
    public function getFirstName() {}
    public function setLastName($name) {}
    public function getLastName() {}
    public function setTitle($title) {}
    public function getTitle() {}
}

class TextPerson
{
    protected $_person;

    public function __construct(Person $person)
    {
        $this-&gt;_person = $person;
    }

    public function __call($method, $args)
    {
        if (!method_exists($this-&gt;_person, $method)) {
            throw new Exception(&#039;Invalid method called on HtmlPerson: &#039;
                .  $method);
        }
        return call_user_func_array(array($this-&gt;_person, $method), $args);
    }

    public function __toString()
    {
        return $this-&gt;_person-&gt;getTitle() . &#039; &#039;
            . $this-&gt;_person-&gt;getFirstName() . &#039; &#039;
            . $this-&gt;_person-&gt;getLastName();
    }
}
</pre>


        <p class="para">
            In this example, you pass your <span class="classname">Person</span> instance to the
            <span class="classname">TextPerson</span> constructor. By using method overloading, you are able
            to continue to call all the methods of <span class="classname">Person</span> -- to set the first
            name, last name, or title -- but you also now gain a string representation via the
             <span class="methodname">__toString()</span> method.
        </p>

        <p class="para">
            This latter example is getting close to how <span class="classname">Zend_Form</span> decorators
            work. The key difference is that instead of a decorator wrapping the element, the
            element has one or more decorators attached to it that it then injects itself into in
            order to render. The decorator then can access the element&#039;s methods and properties in
            order to create a representation of the element -- or a subset of it.
        </p>
    </div>

    <div class="section" id="learning.form.decorators.simplest.first-decorator"><div class="info"><h1 class="title">Creating Your First Decorator</h1></div>
        

        <p class="para">
            <span class="classname">Zend_Form</span> decorators all implement a common interface,
            <span class="classname">Zend_Form_Decorator_Interface</span>. That interface provides
            the ability to set decorator-specific options, register and retrieve the element, and
            render. A base decorator, <span class="classname">Zend_Form_Decorator_Abstract</span>, provides
            most of the functionality you will ever need, with the exception of the rendering logic.
        </p>

        <p class="para">
            Let&#039;s consider a situation where we simply want to render an element as a standard form
            text input with a label. We won&#039;t worry about error handling or whether or not the
            element should be wrapped within other tags for now -- just the basics. Such a decorator
            might look like this:
        </p>

        <pre class="programlisting brush: php">
class My_Decorator_SimpleInput extends Zend_Form_Decorator_Abstract
{
    protected $_format = &#039;&lt;label for=&quot;%s&quot;&gt;%s&lt;/label&gt;&#039;
                       . &#039;&lt;input id=&quot;%s&quot; name=&quot;%s&quot; type=&quot;text&quot; value=&quot;%s&quot;/&gt;&#039;;

    public function render($content)
    {
        $element = $this-&gt;getElement();
        $name    = htmlentities($element-&gt;getFullyQualifiedName());
        $label   = htmlentities($element-&gt;getLabel());
        $id      = htmlentities($element-&gt;getId());
        $value   = htmlentities($element-&gt;getValue());

        $markup  = sprintf($this-&gt;_format, $name, $label, $id, $name, $value);
        return $markup;
    }
}
</pre>


        <p class="para">
            Let&#039;s create an element that uses this decorator:
        </p>

        <pre class="programlisting brush: php">
$decorator = new My_Decorator_SimpleInput();
$element   = new Zend_Form_Element(&#039;foo&#039;, array(
    &#039;label&#039;      =&gt; &#039;Foo&#039;,
    &#039;belongsTo&#039;  =&gt; &#039;bar&#039;,
    &#039;value&#039;      =&gt; &#039;test&#039;,
    &#039;decorators&#039; =&gt; array($decorator),
));
</pre>


        <p class="para">
            Rendering this element results in the following markup:
        </p>

        <pre class="programlisting brush: html">
&lt;label for=&quot;bar[foo]&quot;&gt;Foo&lt;/label&gt;
&lt;input id=&quot;bar-foo&quot; name=&quot;bar[foo]&quot; type=&quot;text&quot; value=&quot;test&quot;/&gt;
</pre>


        <p class="para">
            You could also put this class in your library somewhere, inform your element of that
            path, and refer to the decorator as simply &quot;SimpleInput&quot; as well:
        </p>

        <pre class="programlisting brush: php">
$element = new Zend_Form_Element(&#039;foo&#039;, array(
    &#039;label&#039;      =&gt; &#039;Foo&#039;,
    &#039;belongsTo&#039;  =&gt; &#039;bar&#039;,
    &#039;value&#039;      =&gt; &#039;test&#039;,
    &#039;prefixPath&#039; =&gt; array(&#039;decorator&#039; =&gt; array(
        &#039;My_Decorator&#039; =&gt; &#039;path/to/decorators/&#039;,
    )),
    &#039;decorators&#039; =&gt; array(&#039;SimpleInput&#039;),
));
</pre>


        <p class="para">
            This gives you the benefit of re-use in other projects, and also opens the door for
            providing alternate implementations of that decorator later.
        </p>

        <p class="para">
            In the next section, we&#039;ll look at how to combine decorators in order to create
            composite output.
        </p>
    </div>
</div>
        <hr />

            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="learning.form.decorators.intro.html">Introduction</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="learning.form.decorators.html">Understanding and Using Zend Form Decorators</a></span><br />
                        <span class="home"><a href="manual.html">Programmer's Reference Guide</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="learning.form.decorators.layering.html">Layering Decorators</a></div>
                    </td>
                </tr>
            </table>
</td>
        <td style="font-size: smaller;" width="15%"> <style type="text/css">
#leftbar {
	float: left;
	width: 186px;
	padding: 5px;
	font-size: smaller;
}
ul.toc {
	margin: 0px 5px 5px 5px;
	padding: 0px;
}
ul.toc li {
	font-size: 85%;
	margin: 1px 0 1px 1px;
	padding: 1px 0 1px 11px;
	list-style-type: none;
	background-repeat: no-repeat;
	background-position: center left;
}
ul.toc li.header {
	font-size: 115%;
	padding: 5px 0px 5px 11px;
	border-bottom: 1px solid #cccccc;
	margin-bottom: 5px;
}
ul.toc li.active {
	font-weight: bold;
}
ul.toc li a {
	text-decoration: none;
}
ul.toc li a:hover {
	text-decoration: underline;
}
</style>
 <ul class="toc">
  <li class="header home"><a href="manual.html">Programmer's Reference Guide</a></li>
  <li class="header up"><a href="manual.html">Programmer's Reference Guide</a></li>
  <li class="header up"><a href="learning.html">Learning Zend Framework</a></li>
  <li class="header up"><a href="learning.form.decorators.html">Understanding and Using Zend Form Decorators</a></li>
  <li><a href="learning.form.decorators.intro.html">Introduction</a></li>
  <li class="active"><a href="learning.form.decorators.simplest.html">Decorator Basics</a></li>
  <li><a href="learning.form.decorators.layering.html">Layering Decorators</a></li>
  <li><a href="learning.form.decorators.individual.html">Rendering Individual Decorators</a></li>
  <li><a href="learning.form.decorators.composite.html">Creating and Rendering Composite Elements</a></li>
  <li><a href="learning.form.decorators.conclusion.html">Conclusion</a></li>
 </ul>
 </td>
    </tr>
</table>

<script type="text/javascript" src="../js/shCore.js"></script>
<script type="text/javascript" src="../js/shAutoloader.js"></script>
<script type="text/javascript" src="../js/main.js"></script>

</body>
</html>